﻿#pragma once
#ifndef VF_TCPSERVER_H
#define VF_TCPSERVER_H
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include <vf_tcpclient.h>

namespace VFAdapter {

class MyTcpServer : public boost::enable_shared_from_this<MyTcpServer>,
                    boost::noncopyable {
private:
  MyTcpServer();

public:
  typedef boost::shared_ptr<MyTcpServer> pointer;
  typedef boost::system::error_code error_code;
  static boost::shared_ptr<MyTcpServer> Create();

  void Listen();
  uint16_t GetPort() const;
  std::string GetReturnData() const;

private:
  void ListenHandler(const error_code &ec);
  void StartRead();
  void ReadHandler(const error_code &ec);
  void Stop();

private:
  boost::asio::io_context m_services;
  boost::asio::ip::tcp::endpoint m_ep;
  boost::asio::ip::tcp::socket m_sock;
  boost::asio::ip::tcp::acceptor m_accept;
  char m_receiveBuf[1024];
  std::string m_rtData;
  // 设置5分钟交互时间，如没有结果，则停止
  boost::asio::deadline_timer m_timer;
};

struct TcpListen {
private:
  boost::asio::io_context m_services;
  boost::asio::ip::tcp::acceptor acceptor_;
  boost::asio::deadline_timer m_timer;

private:
  boost::asio::awaitable<void> Listen(std::string &msgReceived) {

    try {
      // 开始等待连接
      boost::asio::ip::tcp::socket socket =
          co_await acceptor_.async_accept(boost::asio::use_awaitable);

      // 连接后，接受消息
      char receiveBuf[1024];
      memset(receiveBuf, 0, sizeof(receiveBuf));
      co_await socket.async_receive(boost::asio::buffer(receiveBuf),
                                    boost::asio::use_awaitable);

      // 接受消息后，停止服务
      msgReceived = std::string(receiveBuf);
      socket.close();
      m_services.stop();
    } catch (std::exception &e) {
      m_services.stop();
    }
  }

public:
  TcpListen()
      : acceptor_(m_services, boost::asio::ip::tcp::endpoint(
                                  boost::asio::ip::tcp::v4(), 0)),
        m_timer(m_services) {}

  ~TcpListen() { m_services.stop(); }
  uint16_t GetPort() const { return acceptor_.local_endpoint().port(); }
  void StartListen(std::string &msgReceived) {
    try {
      // 设置5分钟超时
      m_timer.expires_from_now(boost::posix_time::minutes(5));
      // 超时后停止服务
      m_timer.async_wait([&](auto ec) { m_services.stop(); });

      // 启动监听任务
      co_spawn(m_services, Listen(msgReceived), boost::asio::detached);

      m_services.run();
    } catch (std::exception &e) {
      std::printf("Exception: %s\n", e.what());
      m_services.stop();
    }
  }
};

} // namespace VFAdapter

#endif